package com.tanhua.dubbo.api.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.tanhua.dubbo.api.SoulTestApi;
import com.tanhua.dubbo.enums.LevelType;
import com.tanhua.dubbo.pojo.Questions;
import com.tanhua.dubbo.pojo.TestReport;
import com.tanhua.dubbo.pojo.TestSoul;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@DubboService(version = "1.0.0")
public class SoulTestApiImpl implements SoulTestApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final String SOUL_REDIS_KEY = "SOUL_REDIS_";

    private String getSoulRedisKey(Long userId) {
        return SOUL_REDIS_KEY + userId;
    }

    @Override
    public List<TestSoul> findSoulQueue(Long userId) {
        //查询当前用户等级的灵魂测试题
        String redisKey = SOUL_REDIS_KEY + userId;
        String redisValue = this.redisTemplate.opsForValue().get(redisKey);
        if (StrUtil.isEmpty(redisValue)) {
            //等级从1->3 初级 -中级- 高级
            redisValue = "1";
            this.redisTemplate.opsForValue().set(redisKey, redisValue);
        }
        //通过等级直接查询mongodb对应的试题等级数据
        return Arrays.asList(getSoulTest(LevelType.ONE, redisValue),
                getSoulTest(LevelType.ONE, redisValue),
                getSoulTest(LevelType.TWO, redisValue),
                getSoulTest(LevelType.TWO, redisValue),
                getSoulTest(LevelType.THREE, redisValue));
    }

    /**
     * 把初中高级灵魂测试各拉取一个,放回前台
     *
     * @param levelType
     */
    private TestSoul getSoulTest(LevelType levelType, String redisValue) {
        Query query = Query.query(Criteria.where("level").is(levelType.name()));
        TestSoul testSoul = this.mongoTemplate.findOne(query, TestSoul.class);
        if (testSoul == null) {
            return null;
        }
        //判断试卷是否锁定
        testSoul.setIsLock(Convert.toInt(redisValue) >= levelType.getValue() ? 0 : 1);
        //试题填充, 目前没有什么条件去筛选合适的题目针对个人

        // 去定做一个试题集
        PageRequest pageRequest = PageRequest.of(0, 20, Sort.by(Sort.Order.desc("created")));

        query = new Query().with(pageRequest);
        List<Questions> questions = this.mongoTemplate.find(query, Questions.class);
        if (CollUtil.isEmpty(questions)) {
            return null;
        }

        //打乱顺序取10道题
        Collections.shuffle(questions);
        List<Questions> questionList = ListUtil.sub(questions, 0, 10);
        //设置星级 -->根据分数
        int sum = 0;
        for (Questions question : questionList) {
            sum += question.getStar();
        }
        testSoul.setStar(sum / 10);
        testSoul.setQuestions(questionList);

        return testSoul;
    }

    /**
     * 评分生成testReport
     *
     * @return
     */
    @Override
    public void questionGet(TestReport testReport) {
        //修改试卷等级
        String redisKey=SOUL_REDIS_KEY + testReport.getUserId();
        int num = Convert.toInt(this.redisTemplate.opsForValue().get(redisKey));
        //等级到 3 不做改变,已经最高级
        if (num<3){
            this.redisTemplate.opsForValue().set(redisKey,Convert.toStr(num+1));
        }
        this.mongoTemplate.save(testReport);
    }

    @Override
    public TestReport findReport(String soulId, Long userId) {
        TestReport testReport = null;
        //抽象自己的灵魂测试报告
        if (StrUtil.isNotEmpty(soulId)) {
            testReport = this.mongoTemplate.findById(new ObjectId(soulId), TestReport.class);
        }

        if (null == testReport) {
            //没有查询到就把最近的一次查询结果给到前端
            return this.mongoTemplate.
                    findOne(Query.query(Criteria.where("userId").is(userId)).with(Sort.by(Sort.Order.desc("created"))), TestReport.class);
        }
        return testReport;
    }

    @Override
    public List<Object> findAsReport(String nature, Long userId) {
        PageRequest pageRequest = PageRequest.of(0, 10, Sort.by(Sort.Order.desc("created")));
        Query query = Query.query(Criteria.where("userId").nin(userId)).with(pageRequest);
        List<TestReport> testReports = this.mongoTemplate.find(query, TestReport.class);
        if (CollUtil.isEmpty(testReports)) {
            return Collections.emptyList();
        }
        return CollUtil.getFieldValues(testReports, "userId");
    }

    @Override
    public Questions findById(String qId) {
        return this.mongoTemplate.findById(new ObjectId(qId), Questions.class);
    }
}
